
#include "commmsg.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "cmdmuse.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_MUSE_OPT, CCmdMuseOpt);
int CCmdMuseOpt::Do(void* pData)
{
    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_MUSE_OPT ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_MUSE_OPT,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    _uiGID = stReq.gid();
    _bIsMusing = false;
    _bNotifyOther = false;
    iRet = pstMainCtrl->CheckLogin(_uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdMuseOpt::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, _uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, _uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);

    int iIndex = 0;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    //检查系统是否开启
    if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_12, stPlayerBaseInfo, stPlayerOnlineData))
    {
        return AnsClients(ERROR_SYS_NOT_OPEN);
    }

    MsgMuseInfo * pstMuse = stAns.mutable_muse_info();
    switch (stReq.opt())
    {
    case 1:  //获取用户的冥想信息
        {
            bool bOldStat = stPlayerDetailInfo._stMuseData.IsMusing();
            iRet = pstMainCtrl->m_stMuseMgr.GetMuseInfo(stPlayerBaseInfo, stPlayerDetailInfo._stMuseData, *pstMuse);
            if (stPlayerDetailInfo._stMuseData.IsMusing() != bOldStat)  //结算的过程中有可能结束冥想
            {
                _bIsMusing = stPlayerDetailInfo._stMuseData.IsMusing();
                _bNotifyOther = true;
            }
        }
        break;

    case 2:   //进入冥想
        {
            iRet = pstMainCtrl->m_stMuseMgr.StartMuse(stPlayerBaseInfo, stPlayerDetailInfo._stMuseData, *pstMuse);
            if (RET_OK == iRet)
            {
                _bIsMusing = true;
                _bNotifyOther = true;

                //触发任务
                pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnlineData._stUserTask, TASK_OPT_ID_109, 1);
            }
          }
        break;

    case 3:   //退出冥想
        {
            iRet = pstMainCtrl->m_stMuseMgr.StopMuse(stPlayerBaseInfo, stPlayerDetailInfo._stMuseData);
            if (RET_OK == iRet)
            {
                pstMuse->set_is_musing(false);

                _bIsMusing = false;
                _bNotifyOther = true;
            }
        }
        break;

    default:
        return AnsClients(stReq.opt());
    }

    //保存数据
    if (iRet == RET_OK)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        stKey.m_u64ID = stPlayerDetailInfo._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);
    }

    if (_bNotifyOther)
    {
        pstMainCtrl->m_stMuseMgr.NotifyMapUsers (stPlayerOnlineData, _bIsMusing);
    }

    return AnsClients(iRet);
}

int CCmdMuseOpt::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_opt(stReq.opt());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}